package com.jbp.aspect;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.jbp.model.User;
import com.jbp.service.PropertyService;
import com.jbp.utils.encryptUtils.AesEncryptUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;

/**
 * 这里实现了HttpInputMessage，封装一个解密AES请求体的DecryptInputMessage
 */
class DecryptInputMessageAES implements HttpInputMessage {
    private static final Logger logger = LoggerFactory.getLogger(DecryptInputMessageAES.class);

    private HttpHeaders headers;
    private InputStream body;
    private User user;

    public DecryptInputMessageAES(HttpInputMessage httpInputMessage, User user) throws IOException {
        this.headers = httpInputMessage.getHeaders();
        this.user = user;
        this.body = decrypt(httpInputMessage.getBody());
    }

    private InputStream decrypt(InputStream body) throws IOException {
        StringWriter writer = new StringWriter();
        IOUtils.copy(body, writer, StandardCharsets.UTF_8.name());
        String jsonStr = writer.toString();
        Gson gson = new Gson();
        JsonElement element = gson.fromJson (jsonStr, JsonElement.class);
        JsonObject jsonObj = element.getAsJsonObject();
        String encryptedData = jsonObj.get("data").getAsString();

        long beforeDecrypt = System.currentTimeMillis();
        // 获取用户对象，得到用户的解密参数
        String aesVipara = user.getAesVipara();
        String aesKey = user.getAesKey();
        String decryptedData = AesEncryptUtil.decrypt(encryptedData, aesVipara, aesKey);
        long afterDecrypt = System.currentTimeMillis();
        //logger.info(String.format("decrypted data: %s", decryptedData));
        //logger.info(String.format("decrypt costs: %s", (afterDecrypt-beforeDecrypt)));
        InputStream stream = new ByteArrayInputStream(decryptedData.getBytes(StandardCharsets.UTF_8));
        return stream;
    }

    @Override
    public InputStream getBody() {
        return body;
    }

    @Override
    public HttpHeaders getHeaders() {
        return headers;
    }
}
